package com.cn.onetrip.view;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import com.cn.onetrip.activity.R;
import com.cn.onetrip.activity.ScenicVideoPlayActivity;

public class VideoPlayer extends RelativeLayout implements Callback, 
			OnBufferingUpdateListener, OnPreparedListener, OnCompletionListener, OnErrorListener{
	
	public static final int START_LOADING = 0;
	public static final int LOADING_END = 1;
	public static final int PREPPARED = 2;
	public static final int PLAYING_END = 3;
	
	private Activity context;
	private SurfaceView surfaceView;
	private ImageButton playButton;
	private SeekBar skbProgress;
	private TextView curTime, totalTime;
	private RelativeLayout controller;
	
	private int videoWidth;
	private int videoHeight;
	public MediaPlayer mediaPlayer;
	private SurfaceHolder surfaceHolder;
	private Handler mHandler;
	private Timer mTimer;
	private Timer mControlTimer;
	private Date startTime;
	private String videoUrl;
	private boolean isPlaying = false;
	
	private int mPositionWhenPaused = -1;

	public VideoPlayer(Context context) {
		super(context);
		this.context = (Activity) context;
	}

	public VideoPlayer(Context context, AttributeSet attr) {
		super(context, attr);
		this.context = (Activity) context;
	}
	
	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		
		surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView1);
		playButton = (ImageButton) this.findViewById(R.id.btn_play);
		skbProgress = (SeekBar) this.findViewById(R.id.video_seek_bar);
		curTime = (TextView) findViewById(R.id.tv_cur_time);
		totalTime = (TextView) findViewById(R.id.tv_total_time);
		controller = (RelativeLayout)findViewById(R.id.layout_controller);
		
		if (surfaceView != null) {
			playButton.setOnClickListener(new ClickEvent());
			surfaceView.setOnClickListener(new ClickEvent());

			surfaceHolder = surfaceView.getHolder();
			surfaceHolder.addCallback(this);
			surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		}
	}
	
	public void startPlaying(String url, Handler handler) {
		mHandler = handler;
		videoUrl = url;
		if (mediaPlayer != null)
			playUrl();
	}

	private void startProgressTimer() {
		if (mTimer != null)
			mTimer.cancel();

		mTimer = new Timer();

		TimerTask mTimerTask = new TimerTask() {
			@Override
			public void run() {
				if (mediaPlayer == null)
					return;
				if (mediaPlayer.isPlaying() && skbProgress.isPressed() == false) {
					handleProgress.sendEmptyMessage(0);
				}
				
				Log.e("progress", "progress");
			}
		};

		mTimer.schedule(mTimerTask, 100, 100);
	}

	Handler handleProgress = new Handler() {
		public void handleMessage(Message msg) {

			int position = mediaPlayer.getCurrentPosition();
			int duration = mediaPlayer.getDuration();

			if (duration > 0) {
				long pos = skbProgress.getMax() * position / duration;
				skbProgress.setProgress((int) pos);
				totalTime.setText(formatTime(mediaPlayer.getDuration()));
				curTime.setText(formatTime(position));
			}
		};
	};

	private void startControlTimer() {

		mControlTimer = new Timer();
		startTime = new Date(System.currentTimeMillis());
		TimerTask taskcc = new TimerTask() {

			public void run() {
				context.runOnUiThread(new Runnable() {
					@Override
					public void run() {
						Date endTime = new Date(System.currentTimeMillis());
						long diff = endTime.getTime() - startTime.getTime();
						if (diff > 5000) {
							controller.setVisibility(View.GONE);
							mControlTimer.cancel();
						}
					}
				});

			}
		};

		mControlTimer.schedule(taskcc, 50, 50);
	}
	
	// *****************************************************
	public int getCurPos() {
		return mediaPlayer.getCurrentPosition();
	}
	
	public void seekTo(int pos) {
		mediaPlayer.seekTo(pos);
		skbProgress.setProgress(pos*skbProgress.getMax()/mediaPlayer.getDuration());
	}
	
	public void play() {
		playButton.setEnabled(true);
		mediaPlayer.start();
		isPlaying = true;
		startProgressTimer();
	}

	private void playUrl() {
		try {
			playButton.setEnabled(false);
			isPlaying = false;
			mediaPlayer.reset();
			mediaPlayer.setDataSource(videoUrl);
			mediaPlayer.prepareAsync();
			// mediaPlayer.start();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void pause() {
		stopTimer();
		mediaPlayer.pause();
		isPlaying = false;
	}

	public void stop() {
		if (mediaPlayer != null) {
			mediaPlayer.stop();
			mediaPlayer.release();
			mediaPlayer = null;
		}
	}
	
	public void stopTimer() {
		if (mTimer != null)
			mTimer.cancel();
		
		if (mControlTimer != null)
			mControlTimer.cancel();
	}

	@Override
	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
		Log.e("mediaPlayer", "surface changed");
	}

	@Override
	public void surfaceCreated(SurfaceHolder arg0) {
		try {
			if (mediaPlayer == null) {
				mediaPlayer = new MediaPlayer();
			}
			
			mediaPlayer.setDisplay(surfaceHolder);
			mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
			mediaPlayer.setOnBufferingUpdateListener(this);
			mediaPlayer.setOnPreparedListener(this);
			mediaPlayer.setOnCompletionListener(this);
			mediaPlayer.setOnErrorListener(this);
			skbProgress.setOnSeekBarChangeListener(new SeekBarChangeEvent());
			
			playUrl();
		} catch (Exception e) {
			Log.e("mediaPlayer", "error", e);
			Log.e("mediaPlayer", "error");
		}
		Log.e("mediaPlayer", "surface created");
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
		Log.e("mediaPlayer", "surface destroyed");
		isPlaying = false;
		mPositionWhenPaused = getCurPos();
	}

	@Override
	public void onPrepared(MediaPlayer mp) {
		videoWidth = mediaPlayer.getVideoWidth();
		videoHeight = mediaPlayer.getVideoHeight();
		if (videoWidth != 0 && videoHeight != 0) {
			if (mPositionWhenPaused >= 0) {
				seekTo(mPositionWhenPaused);
				mPositionWhenPaused = -1;
			}
			
			play();
			mHandler.sendEmptyMessage(LOADING_END);
			startControlTimer();
		}
		
		Log.e("mediaPlayer", "onPrepared");
	}

	@Override
	public void onCompletion(MediaPlayer mediaPlayer) {
		Log.e("mediaPlayer", "onCompletion");
//		Log.e(mediaPlayer.getCurrentPosition() + "% getCurrentPosition", 
//				mediaPlayer.getDuration() + "% getDuration");
		mHandler.sendEmptyMessage(PLAYING_END);
	}

	@Override
	public void onBufferingUpdate(MediaPlayer arg0, int bufferingProgress) {
		if (!isPlaying)
			return;
		
		skbProgress.setSecondaryProgress(bufferingProgress);
		int currentProgress = skbProgress.getMax()
				* mediaPlayer.getCurrentPosition() / mediaPlayer.getDuration();
		Log.e(currentProgress + "% play", bufferingProgress + "% buffer");

		if (bufferingProgress < currentProgress) 
			mHandler.sendEmptyMessage(START_LOADING);
		else 
			mHandler.sendEmptyMessage(LOADING_END);
	}

	class ClickEvent implements OnClickListener {

		@Override
		public void onClick(View v) {
			if (v == playButton) {
				if (isPlaying) {
					pause();
					playButton.setBackgroundResource(R.drawable.video_play_button);
				} else {
					play();
					playButton.setBackgroundResource(R.drawable.video_pause_button);
				}
				
				startControlTimer();
			} else if (v == surfaceView) {
				if (controller.getVisibility() == View.VISIBLE) {
					controller.setVisibility(View.GONE);
				} else {
					controller.setVisibility(View.VISIBLE);
					startControlTimer();
				}
			}
		}
	}

	class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {
		int progress;

		@Override
		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {
			this.progress = progress * mediaPlayer.getDuration()
					/ seekBar.getMax();
		}

		@Override
		public void onStartTrackingTouch(SeekBar seekBar) {

		}

		@Override
		public void onStopTrackingTouch(SeekBar seekBar) {		
			mediaPlayer.seekTo(progress);
			startControlTimer();
		}
	}
	
	private String formatTime(long time) {
		return String.format("%02d:%02d", time / 1000 / 60 % 60, time / 1000 % 60);
	}

	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		// TODO Auto-generated method stub
		return false;
	}

}